/**
  ******************************************************************************
  * @file    bootloader.h
  * @author  ashuai0110
  * @version V2.3
  * @date    2024-07-01
  * @brief   升级引导程序
  *
  ******************************************************************************
  * @attention
  *
  * 版权声明:内容为编者(ashuai0110)原创,使用请注明出处,当然,你也可以不这样做^_^
  * 出处链接:https://gitee.com/ashuai0110/mcu_reuse_development_module.git
  *
  ******************************************************************************
  */

#ifndef __BOOTLOADER_H
#define __BOOTLOADER_H

#ifdef __cplusplus
extern "C" {
#endif

/* 包含头文件-----------------------------------------------------------------*/
#include "common_include.h"

/**
 * @addtogroup bootloader
 * @{
 */

/**
 * @addtogroup bootloader_
 * @{
 */

/* 宏定义---------------------------------------------------------------------*/
/**
 * @defgroup bootloader_global_macros bootloader global macros
 * @{
 */

/* 设置栈顶指针接口(不适配时用户需自行更换) */
#define BOOT_SET_STACK_POINT(addr)          ( __set_MSP((addr)) )

/**
 * @defgroup boot_mcu_info bootloader mcu info
 * @brief    MCU ROM,RAM,升级参数设置(用户按需修改)
 * @{
 */
#define BOOT_ROM_START_ADDR                 (0x8000000) /*!< MCU ROM起始地址 */
#define BOOT_RAM_START_ADDR                 (0x20000000) /*!< MCU RAM起始地址 */
#define BOOT_RAM_TOTAL_SIZE                 (0x2800)    /*!< MCU RAM总大小 */
/* /-------------------flash分区规划------------------\
 * | bootloader | application | factory | updata info |
 * |    xxx     |     xxx     |   xxx   |      8      |
 * \--------------------------------------------------/ */
#define BOOT_ADDR_OFFSET                    (0x0) /*!< 升级引导程序起始地址偏移量 */
#define BOOT_SIZE_MAX                       (0x2C00) /*!< 升级引导程序最大大小 */
#define BOOT_APP_ADDR_OFFSET                (BOOT_ADDR_OFFSET + BOOT_SIZE_MAX + 0x0) /*!< 应用程序起始地址偏移量 */
#define BOOT_APP_SIZE_MAX                   (0x2800) /*!< 应用程序最大大小 */
#define BOOT_FACTORY_ADDR_OFFSET            (BOOT_APP_ADDR_OFFSET + BOOT_APP_SIZE_MAX + 0x0) /*!< 备份(出厂)程序起始地址偏移量 */
#define BOOT_FACTORY_SIZE_MAX               (0x2800) /*!< 备份(出厂)程序最大大小 */
/* 升级信息存放起始地址偏移量 (应处于BOOT,APP,FACTORY存储之外的FLASH扇区,保证不会被意外擦除或改写) */
#define BOOT_INFO_ADDR_OFFSET               (BOOT_FACTORY_ADDR_OFFSET + BOOT_FACTORY_SIZE_MAX  + 0x0)
#define BOOT_VERSION                        (0x100) /*!< bootloader版本号 0x100 = V1.0.0 */
/**
 * @}
 */

/**
 * @defgroup boot_updata_flag bootloader updata flag
 * @{
 */
#define BOOT_UPDATA_FLAG                    (0x02468ACE) /*!< 需要升级标志 */
#define BOOT_TO_APP_FLAG                    (0x55555555) /*!< 跳转APP/升级成功标志 */
#define BOOT_TO_FACTORY_FLAG                (0xAAAAAAAA) /*!< 跳转FACTORY/升级失败标志 */
/**
 * @}
 */

/**
 * @}
 */

/* 类型定义-------------------------------------------------------------------*/
/**
 * @defgroup bootloader_global_types bootloader global types
 * @{
 */

/**
  * @brief  程序跳转函数
  *
  * @param  None
  *
  * @retval None
  */
typedef void (* boot_jump_fn_t)(void);

/**
  * @brief  读/写flash
  *
  * @param  startAddr : 起始地址
  *
  * @param  pBuf      : 数据缓冲区
  *
  * @param  len       : 读/写数量byte
  *
  * @retval 0:读/写成功  1:读/写失败
  */
typedef uint8_t (* boot_flash_rw_fn_t)(uint32_t startAddr, void *pBuf, uint32_t len);

/**
  * @brief  擦除flash
  *
  * @param  startAddr : 起始地址
  *
  * @param  bytes     : 擦除总字节数量
  *
  * @retval 0:擦除成功  1:擦除失败
  */
typedef uint8_t (* boot_flash_erase_fn_t)(uint32_t startAddr, uint32_t bytes);

/** 
  * @brief  升级参数 structure definition
  */
typedef struct boot_info {
    uint32_t updataFlag;  /*!< 升级标志 @ref boot_updata_flag */
    uint16_t bootVersion; /*!< bootloader版本 0x100代表V1.0.0 */
    uint16_t appVersion;  /*!< application版本 0x100代表V1.0.0 */
} boot_info_t;

/** 
  * @brief  升级引导程序 structure definition
  */
typedef struct bootloader {
    uint32_t writedSize;   /*!< 已写入数据大小 */
    boot_info_t bootInfo;  /*!< 升级参数 */
    
    boot_jump_fn_t jumpFn; /*!< 跳转应用程序函数 */
    
    void (*mcuRebootFn)(void);          /*!< MCU重启接口 */
    boot_flash_erase_fn_t flashEraseFn; /*!< 擦除FLASH接口 */
    boot_flash_rw_fn_t flashReadFn;     /*!< 读取FLASH接口 */
    boot_flash_rw_fn_t flashWriteFn;    /*!< 写入FLASH接口 */
} bootloader_t;

/**
 * @}
 */

/* 全局变量-------------------------------------------------------------------*/

/* 函数原型-------------------------------------------------------------------*/
/**
 * @addtogroup bootloader_global_functions
 * @{
 */

void boot_init(boot_flash_erase_fn_t flashErase, boot_flash_rw_fn_t flashRead, boot_flash_rw_fn_t flashWrite);

void boot_check_updata_flag(void);

uint8_t boot_erase_application(uint32_t appSize);
uint8_t boot_program_application(void *data, uint16_t len);

void boot_program_updata_flag(uint32_t updataFlag);
void boot_program_app_version(uint16_t appVersion);

void boot_to_application(void);
void boot_to_factory(void);
void boot_to_bootloader(void);

/* 弱定义函数 */
void boot_recover_all(void);

/**
 * @}
 */

/**
 * @}
 */

/**
 * @}
 */

#ifdef __cplusplus
}
#endif

#endif /* bootloader.h */
